Skip to content

Restore dft_stac_cube() AOI-polygon clip via terra::mask (#32)#37

Merged
NewGraphEnvironment merged 6 commits into
mainfrom
32-dft-stac-cube-restore-aoi-polygon-clip-f
Jul 9, 2026
Merged

Restore dft_stac_cube() AOI-polygon clip via terra::mask (#32)#37
NewGraphEnvironment merged 6 commits into
mainfrom
32-dft-stac-cube-restore-aoi-polygon-clip-f

Conversation

@NewGraphEnvironment

@NewGraphEnvironment NewGraphEnvironment commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • dft_stac_cube() gains clip (default TRUE), restoring AOI-polygon-tight output removed in Continuous index-trajectory change detection (Sentinel-2 + BFAST) for floodplain reaches #30. The assembled index stack is masked to the AOI polygon with terra::mask() client-side (helper stac_cube_clip(), mirroring dft_stac_fetch()) — never gdalcubes::filter_geom(), which segfaults / returns an all-NA cube on the pinned build. Out-of-polygon cells become NA on every layer, so dft_rast_break()/dft_rast_trend() skip them via their rowSums(!is.na) >= min_obs gate and the reduced raster is polygon-tight with no caller-side mask. clip = FALSE keeps the full bbox.
  • clip is threaded into both the mask step and the cube cache key, and normalized once (clip <- isTRUE(as.logical(clip))) so a truthy-but-non-TRUE input can't skip the mask yet key as TRUE (which would let a later clip = TRUE read an unclipped cube).

Scope / honest framing

Clips the output only — cube_view(extent = bbox) still streams the full bbox of COGs (the AOI can't be pushed into the read on the pinned gdalcubes build), so fetch time is unchanged. Genuine wins: polygon-tight output by default + a modest reducer speedup (out-of-AOI pixels skipped). This residual is recorded in inst/notes/gdalcubes-pc-gotchas.md.

Behavior change

Direct cube users now get NA outside the AOI by default; the clip is folded into the cube cache key, so existing cached cubes rebuild once. Released as v0.5.0.

Test plan

  • Offline stac_cube_clip() masking test (synthetic raster + polygon) + cube_key(clip = FALSE) != base — network-free contract
  • Opt-in network e2e asserts most bbox cells are fully NA under default clip (example AOI area/bbox ≈ 0.105)
  • devtools::check() clean (0 errors / 0 warnings / 0 notes); full suite 319 pass; lint clean

Related Issues

🤖 Generated with Claude Code

https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz

NewGraphEnvironment and others added 6 commits July 9, 2026 14:36
Restore dft_stac_cube() AOI-polygon clip via client-side terra::mask
(clip = TRUE default), replacing the removed gdalcubes::filter_geom.
Phases + Plan-agent-reviewed findings scaffolded.

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
Failing-first contract for the clip = TRUE restoration:
- cube_key() helper threads `clip`; cube_key(clip = FALSE) != base (guards the
  silent wrong-extent cache-hit if clip is not in the key)
- offline stac_cube_clip() masking test (synthetic raster + half-covering polygon):
  out-of-polygon cells -> NA on every layer, nlyr preserved (network-free)
- opt-in network e2e asserts most bbox cells are fully NA under default clip
  (example AOI area/bbox ~= 0.105)

Confirmed red against current code: FAIL 6 | SKIP 2 | PASS 1.

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
Add `clip = TRUE`: mask the assembled index stack to the AOI polygon with
terra::mask() (mirrors dft_stac_fetch(), never gdalcubes::filter_geom which
segfaults on the pinned build). Out-of-polygon cells become NA on every layer,
so dft_rast_break()/dft_rast_trend() skip them via their rowSums(!is.na) gate,
and the reduced raster is polygon-tight with no caller-side mask.

- new @nord helper stac_cube_clip(stk, aoi) = terra::mask(stk, terra::vect(aoi))
- `clip` threaded into stac_cube_cache_key() (hashed) AND the call site, so
  clip=TRUE/FALSE key distinctly (no wrong-extent cache hit)
- normalize `clip <- isTRUE(as.logical(clip))` once so the mask gate and the key
  can't disagree for truthy-but-non-TRUE inputs (/code-check finding)
- roxygen @param clip + @return rewrite; drop the stale filter_geom comments

Full suite 319 pass, lint clean. clip is default TRUE (restores intended
behavior); clip = FALSE keeps the full bbox.

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
- gdalcubes-pc-gotchas.md: filter_geom bullet now notes the #32 resolution
  (clip restored via cube-level terra::mask in dft_stac_cube(clip=TRUE)) and
  the residual (fetch-time COG streaming stays bbox-bound)
- NEWS.md 0.5.0: dft_stac_cube() clip default, output/behavior change, cache
  rebuild, Closes #32

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
dft_stac_cube() AOI-polygon clip restored (#32). devtools::check() clean
(0 errors / 0 warnings / 0 notes); full suite 319 pass.

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
dft_stac_cube AOI-polygon clip restored via terra::mask (clip = TRUE),
released v0.5.0. Fresh planning/active/ retained.

Relates to NewGraphEnvironment/sred#16

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DKqnW6Fni3tc44Lo5D5fJz
@NewGraphEnvironment NewGraphEnvironment merged commit 0a079b7 into main Jul 9, 2026
1 check passed
@NewGraphEnvironment NewGraphEnvironment deleted the 32-dft-stac-cube-restore-aoi-polygon-clip-f branch July 9, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dft_stac_cube: restore AOI-polygon clip (filter_geom segfault workaround)

1 participant